<?php

namespace App\Models;


use App\Models\Customer\Customer;
use App\Models\Customer\DeviceAccount;
use App\Models\Panx\Product;
use App\Models\Store\Store;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\Access\Authorizable;


/**
 * Class Order
 * @package App\Models
 *
 * @property $id
 * @property $refund_state
 * @property string product_title
 * @property string product_thumb_url
 * @property array product_json_data
 * @property-read string $refund_state_str
 * @method self filterKeyword(?string $keyword)
 * @method self filterStoreId(?int $store_id)
 *
 * @mixin Builder
 */
class Order extends Model
{
    use Authorizable;

    protected $table = 'orders';

    protected $guarded = [];

    protected $casts = [
        'product_json_data' => 'json',
    ];

    const PRODUCT_BELONG_TO_CUSTOMER = 1; // 订单属于客户

    const PRODUCT_BELONG_TO_STORE = 2; // // 订单属于店铺

    const MIRROR_APP_ORDER_TYPE = 'mirror_app_order';

    /**
     * 退款类型
     *
     * @link https://www.youzanyun.com/apilist/structparam/response/StructurizationOrderInfoDetail
     */
    const REFUND_TYPE_BUYER = 1;
    const REFUND_TYPE_CUSTOMER = 2;
    const REFUND_TYPE_ONE_CLICK = 3;

    const REFUND_TYPE_MAP = [
        self::REFUND_TYPE_BUYER     => '买家申请退款',
        self::REFUND_TYPE_CUSTOMER  => '商家主动退款',
        self::REFUND_TYPE_ONE_CLICK => '一键退款',
    ];

    /**
     * 退款状态
     * @link https://www.youzanyun.com/apilist/structparam/response/StructurizationOrderInfoDetail
     *
     * 0:未退款;
     * 1:部分退款中;
     * 2:部分退款成功;
     * 11:全额退款中;
     * 12:全额退款成功
     */
    const NOT_REFUNDABLE = 0;
    const PARTIAL_REFUND = 1;
    const PARTIAL_REFUND_SUCCESS = 2;
    const FULL_REFUND = 11;
    const FULL_REFUND_SUCCESS = 12;

    const REFUND_STATE_DESC = [
        self::NOT_REFUNDABLE         => '-', // 未退款 , 前端不要显示这个状态
        self::PARTIAL_REFUND         => '部分退款中',
        self::PARTIAL_REFUND_SUCCESS => '部分退款成功',
        self::FULL_REFUND            => '全额退款中',
        self::FULL_REFUND_SUCCESS    => '全额退款成功',
    ];

    /**
     * 退款状态详情
     * @link https://www.youzanyun.com/apilist/structparam/response/StructurizationTradeRefundInfoDetail[]
     *
     * 1:买家已经申请退款，等待卖家同意;
     * 10:卖家拒绝退款;
     * 20:卖家已经同意退货，等待买家退货;
     * 30:买家已经退货，等待卖家确认收货;
     * 40:卖家未收到货,拒绝退款;
     * 50:退款关闭;
     * 60:退款成功;
     */
    const ORDER_APPLY_REFUND = 1;
    const ORDER_REJECT_REFUND = 10;
    const ORDER_WAIT_REFUND = 20;
    const ORDER_CONFIRM_REFUND = 30;
    const ORDER_NOT_RECEIVED_REFUND = 40;
    const ORDER_CLOSE_REFUND = 50;
    const ORDER_SUCCESS_REFUND = 60;

    const ORDER_REFUND_DETAIL_STATE = [
        self::NOT_REFUNDABLE            => '未退款',
        self::ORDER_APPLY_REFUND        => '买家已经申请退款，等待卖家同意',
        self::ORDER_REJECT_REFUND       => '卖家拒绝退款',
        self::ORDER_WAIT_REFUND         => '卖家已经同意退货，等待买家退货',
        self::ORDER_CONFIRM_REFUND      => '买家已经退货，等待卖家确认收货',
        self::ORDER_NOT_RECEIVED_REFUND => '卖家未收到货,拒绝退款',
        self::ORDER_CLOSE_REFUND        => '退款关闭',
        self::ORDER_SUCCESS_REFUND      => '退款成功',
    ];

    public function customer()
    {
        return $this->belongsTo(Customer::class);
    }

    public function store()
    {
        return $this->belongsTo(Store::class);

    }

    public function deviceAccount()
    {
        return $this->belongsTo(DeviceAccount::class);
    }

    /**
     * @used-by $refund_state_str
     *
     * @return string
     */
    public function getRefundStateStrAttribute()
    {
        return self::REFUND_STATE_DESC[$this->refund_state];
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function product()
    {
        return $this->belongsTo(Product::class, 'product_id', 'id');
    }

    /**
     * @used-by filterKeyword() - 关键词过滤
     *
     * @param Builder $query
     * @param $keyword
     * @return Builder
     */
    public function scopeFilterKeyword(Builder $query, $keyword)
    {
        if (!$keyword) return $query;

        return $query->where('trad_no', 'like', '%'.$keyword.'%')
            ->orWhere('buyer', 'like', '%'.$keyword.'%')
            ->orWhere(function(Builder $query) use($keyword) {
                $query->whereHas('product', function(Builder $query) use($keyword){
                    $query->where('title', 'like', '%'.$keyword.'%');
                });
            });
    }

    /**
     * @used-by Order::filterStoreId()
     *
     * @param Builder $query
     * @param $store_id
     * @return Order|Builder
     */
    public function scopeFilterStoreId(Builder $query, $store_id)
    {
        if (!$store_id) return $query;

        return $this->where('store_id', $store_id);
    }
}
